package com.idp.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.idp.common.enums.MessageEnum;
import com.idp.common.error.SystemException;
import com.idp.system.dto.SysButtonDto;
import com.idp.system.dto.SysMenuDto;
import com.idp.system.entity.SysButtonEntity;
import com.idp.system.entity.SysMenuEntity;
import com.idp.system.entity.SysRoleButtonEntity;
import com.idp.system.entity.SysRoleMenuEntity;
import com.idp.system.mapper.SysButtonMapper;
import com.idp.system.mapper.SysMenuMapper;
import com.idp.system.mapper.SysRoleButtonMapper;
import com.idp.system.mapper.SysRoleMenuMapper;
import com.idp.system.service.SysMenuService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 菜单Service实现类
 * @author King
 */
@Service
public class SysMenuServiceImpl implements SysMenuService {

	@Autowired
	private SysMenuMapper sysMenuMapper;
	@Autowired
	private SysButtonMapper sysButtonMapper;
	@Autowired
	private SysRoleMenuMapper sysRoleMenuMapper;
	@Autowired
	private SysRoleButtonMapper sysRoleButtonMapper;

	@Override
	public List<SysMenuDto> findByTreeTable(String parentId) {

		return sysMenuMapper.getListByParentId(parentId);
	}

	@Override
	public SysMenuDto getById(String id) {

		SysMenuDto menuDto = new SysMenuDto();
		SysMenuEntity menuEntity = sysMenuMapper.selectById(id);
		BeanUtil.copyProperties(menuEntity, menuDto);

		return menuDto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void add(SysMenuDto sysMenuDto) {

		SysMenuEntity sysMenuEntity = new SysMenuEntity();
		BeanUtil.copyProperties(sysMenuDto, sysMenuEntity);

		if(StrUtil.isEmpty(sysMenuEntity.getParentId())) {
			sysMenuEntity.setParentId("0");
		}

		sysMenuMapper.insert(sysMenuEntity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void update(SysMenuDto sysMenuDto) {

		SysMenuEntity sysMenuEntity = sysMenuMapper.selectById(sysMenuDto.getId());
		if(sysMenuEntity == null) {
			throw new SystemException(MessageEnum.DATA_NOT_EXIST);
		}

		BeanUtil.copyProperties(sysMenuDto, sysMenuEntity);

		if(StrUtil.isEmpty(sysMenuEntity.getParentId())) {
			sysMenuEntity.setParentId("0");
		}

		sysMenuMapper.updateById(sysMenuEntity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(String id) {

		LambdaQueryWrapper<SysMenuEntity> query = new LambdaQueryWrapper<SysMenuEntity>();
		query.eq(SysMenuEntity::getParentId, id);

		List<SysMenuEntity> children = sysMenuMapper.selectList(query);

		if(CollectionUtils.isNotEmpty(children)) {

			throw new SystemException("菜单下存在子菜单无法删除，请先删除子菜单");
		}
		else {

			sysMenuMapper.deleteById(id);

			// 删除角色的菜单权限
			LambdaQueryWrapper<SysRoleMenuEntity> roleMenuQueryWrapper = new LambdaQueryWrapper<>();
			roleMenuQueryWrapper.eq(SysRoleMenuEntity::getMenuId, id);
			sysRoleMenuMapper.delete(roleMenuQueryWrapper);
			// 删除菜单下的按钮
			LambdaQueryWrapper<SysButtonEntity> buttonQueryWrapper = new LambdaQueryWrapper<>();
			buttonQueryWrapper.eq(SysButtonEntity::getMenuId, id);
			sysButtonMapper.delete(buttonQueryWrapper);
			// 删除角色的菜单下按钮权限
			LambdaQueryWrapper<SysRoleButtonEntity> roleButtonQueryWrapper = new LambdaQueryWrapper<>();
			roleButtonQueryWrapper.eq(SysRoleButtonEntity::getMenuId, id);
			sysRoleButtonMapper.delete(roleButtonQueryWrapper);
		}
	}

	@Override
	public List<SysMenuDto> findAllForTree() {

		Map<String, String> params = new HashMap<String, String>();
		params.put("parentId", "0");

		return sysMenuMapper.findAllForTree(params);
	}

	@Override
	public SysMenuDto getButtonsByMenuId(String menuId) {

		return sysMenuMapper.getButtonsByMenuId(menuId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void setButtonsByMenuId(SysMenuDto sysMenuDto) {

		SysMenuDto oldMenu = sysMenuMapper.getButtonsByMenuId(sysMenuDto.getId());

		if(oldMenu == null) {
			throw new SystemException(MessageEnum.DATA_NOT_EXIST);
		}

		Set<String> newButtonIds = new HashSet<String>();

		if(CollectionUtils.isNotEmpty(sysMenuDto.getButtons())) {

			for (SysButtonDto button : sysMenuDto.getButtons()) {

				if(StrUtil.isNotEmpty(button.getId())) {
					newButtonIds.add(button.getId());
				}
			}
		}

		if(CollectionUtils.isNotEmpty(oldMenu.getButtons())) {

			for (SysButtonDto button : oldMenu.getButtons()) {

				if(!newButtonIds.contains(button.getId())) {

					// 删除菜单下的按钮
					sysButtonMapper.deleteById(button.getId());
					// 删除角色的菜单下按钮权限
					LambdaQueryWrapper<SysRoleButtonEntity> roleButtonQueryWrapper = new LambdaQueryWrapper<>();
					roleButtonQueryWrapper.eq(SysRoleButtonEntity::getButtonId, button.getId());
					sysRoleButtonMapper.delete(roleButtonQueryWrapper);
				}
			}
		}

		if(CollectionUtils.isNotEmpty(sysMenuDto.getButtons())) {

			for (SysButtonDto button : sysMenuDto.getButtons()) {
				SysButtonEntity sysButtonEntity = BeanUtil.toBean(button, SysButtonEntity.class);
				if(StrUtil.isNotEmpty(sysButtonEntity.getId())) {
					sysButtonMapper.updateById(sysButtonEntity);
				}
				else {
					sysButtonEntity.setMenuId(sysMenuDto.getId());
					sysButtonMapper.insert(sysButtonEntity);
				}
			}
		}
	}

}
